package com.hymjweb.demo.hymj.master_bill_manage.auto.service;

import com.alibaba.fastjson.JSONObject;
import com.hymjweb.demo.SpringAopUtil;
import com.hymjweb.demo.framework.result.MIniUIGridResultMap;
import com.hymjweb.demo.framework.sys.BaseService;
import com.hymjweb.demo.framework.sys.SysConstant;
import com.hymjweb.demo.framework.util.DataTypeUtil;
import com.hymjweb.demo.framework.util.DateUtil;
import com.hymjweb.demo.hymj.log_manage.aop.annotation.OperationLogger;
import com.hymjweb.demo.hymj.master_bill_manage.auto.bean.BMasterBillAutoBean;
import com.hymjweb.demo.hymj.master_bill_manage.auto.bean.BMasterBillAutoPojo;
import com.hymjweb.demo.hymj.master_bill_manage.auto.mappper.BMasterBillAutoMapper;
import com.hymjweb.demo.hymj.master_bill_manage.load.bean.BNativeBillLoadPojo;
import com.hymjweb.demo.hymj.master_bill_manage.load.service.BNativeBillLoadService;
import com.hymjweb.demo.hymj.master_bill_manage.other_charges.bean.BMasterBillOtherChargePojo;
import com.hymjweb.demo.hymj.master_bill_manage.other_charges.service.BMasterBillOtherChargeService;
import com.hymjweb.demo.hymj.native_bill_manage.bean.BNativeBillPojo;
import com.hymjweb.demo.hymj.native_bill_manage.service.BNativeBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class BMasterBillAutoService extends BaseService {

    @Autowired
    private BMasterBillAutoMapper bMasterBillAutoMapper;

    @Autowired
    private BMasterBillOtherChargeService bMasterBillOtherChargeService;

    @Autowired
    private BNativeBillLoadService bNativeBillLoadService;

    @Autowired
    private BNativeBillService bNativeBillService;

    public BMasterBillAutoBean convertJSONObjToJavaObj(JSONObject jsonMasterBillPojo) {
        BMasterBillAutoBean bean = new BMasterBillAutoBean();
        // 航空主单号 ID
        String id = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("id"));
        bean.setId(id);

        // 承运方式ID
        Long transportWayId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("transportWayId"));
        bean.setTransportWayId(transportWayId);

        // 承运单位ID
        String transportUnitId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("transportUnitId"));
        bean.setTransportUnitId(transportUnitId);

        // 承运单位主单号
        String transportUnitMasterBillCodeIds = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("transportUnitMasterBillCodeIds"));
        bean.setTransportUnitMasterBillCodeIds(transportUnitMasterBillCodeIds);

        // 始发站ID
        String startCityId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("startCityId"));
        bean.setStartCityId(startCityId);

        // 目的站ID
        String destCityId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("destCityId"));
        bean.setDestCityId(destCityId);

        // 线路名称
        String autoLineRoadName = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("autoLineRoadName"));
        bean.setAutoLineRoadName(autoLineRoadName);

        // 派送方式ID
        Long sendWayId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("sendWayId"));
        bean.setSendWayId(sendWayId);

        // 提货点ID
        String pickUpPointId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("pickUpPointId"));
        bean.setPickUpPointId(pickUpPointId);

        // 提货点名称
        String pickUpPointName = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("pickUpPointName"));
        bean.setPickUpPointName(pickUpPointName);

        // 提货点电话
        String pickUpPointPhone = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("pickUpPointPhone"));
        bean.setPickUpPointPhone(pickUpPointPhone);

        // 提货点地址
        String pickUpPointAddress = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("pickUpPointAddress"));
        bean.setPickUpPointAddress(pickUpPointAddress);

        // 车牌号
        String licensePlateNumber = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("licensePlateNumber"));
        bean.setLicensePlateNumber(licensePlateNumber);

        // 走货时间
        Date deliveryTime = DateUtil.strToDate(DataTypeUtil.toStringObject(jsonMasterBillPojo.get("deliveryTime")));
        bean.setDeliveryTime(deliveryTime);

        // 驾驶员
        String driver = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("driver"));
        bean.setDriver(driver);

        // 驾驶员电话
        String driverPhone = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("driverPhone"));
        bean.setDriverPhone(driverPhone);

        // 货物类型ID
        Long goodsTypeId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("goodsTypeId"));
        bean.setGoodsTypeId(goodsTypeId);

        // 总件数
        Long totalNumber = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("totalNumber"));
        bean.setTotalNumber(totalNumber);

        Double actualWeight = DataTypeUtil.toDouble(jsonMasterBillPojo.get("actualWeight"));
        bean.setActualWeight(actualWeight);

        Double chargeableWeight = DataTypeUtil.toDouble(jsonMasterBillPojo.get("chargeableWeight"));
        bean.setChargeableWeight(chargeableWeight);

        Double actualLoadTotalWeight = DataTypeUtil.toDouble(jsonMasterBillPojo.get("actualLoadTotalWeight"));
        bean.setActualLoadTotalWeight(actualLoadTotalWeight);

        Double weightRate = DataTypeUtil.toDouble(jsonMasterBillPojo.get("weightRate"));
        bean.setWeightRate(weightRate);

        Double volume = DataTypeUtil.toDouble(jsonMasterBillPojo.get("volume"));
        bean.setVolume(volume);

        Double volumeRate = DataTypeUtil.toDouble(jsonMasterBillPojo.get("volumeRate"));
        bean.setVolumeRate(volumeRate);

        Double freightAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("freightAmount"));
        bean.setFreightAmount(freightAmount);

        Double otherCharges = DataTypeUtil.toDouble(jsonMasterBillPojo.get("otherCharges"));
        bean.setOtherCharges(otherCharges);

        String otherChargesComment = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("otherChargesComment"));
        bean.setOtherChargesComment(otherChargesComment);


        Long masterBillPaymentMethodId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("masterBillPaymentMethodId"));
        bean.setMasterBillPaymentMethodId(masterBillPaymentMethodId);


        Double totalFreightAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("totalFreightAmount"));
        bean.setTotalFreightAmount(totalFreightAmount);


        // 拉货调整金额，默认是0
        Double dropAmount = DataTypeUtil.toDouble(jsonMasterBillPojo.get("dropAmount"));
        bean.setDropAmount(dropAmount);


        // 结算金额 totalFreightAmount + dropAmount
        Double settlementAmount = totalFreightAmount + dropAmount;
        bean.setSettlementAmount(settlementAmount);

        // 开单日期
        Date openMasterBillDate = DateUtil.strToDate(DataTypeUtil.toStringObject(jsonMasterBillPojo.get("openMasterBillDate")));
        bean.setOpenMasterBillDate(openMasterBillDate);

        // 开单部门ID
        String openMasterBillDepartmentId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("openMasterBillDepartmentId"));
        bean.setOpenMasterBillDepartmentId(openMasterBillDepartmentId);

        // 开单人ID
        String openMasterBillUserId = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("openMasterBillUserId"));
        bean.setOpenMasterBillUserId(openMasterBillUserId);

        // 运费结清状态ID
        Long freightAmountStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("freightAmountStatusId"));
        bean.setFreightAmountStatusId(freightAmountStatusId);

        // 拉货状态ID
        Long dropStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("dropStatusId"));
        bean.setDropStatusId(dropStatusId);

        // 对账状态ID
        Long accountCheckStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("accountCheckStatusId"));
        bean.setAccountCheckStatusId(accountCheckStatusId);

        // 结算状态ID
        Long settlementStatusId = DataTypeUtil.toLongObject(jsonMasterBillPojo.get("settlementStatusId"));
        bean.setSettlementStatusId(settlementStatusId);

        // 备注
        String comment = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("comment"));
        bean.setComment(comment);


        // 配载的分单号
        String loadNativeBillIds = DataTypeUtil.toStringObject(jsonMasterBillPojo.get("loadNativeBillIds"));
        bean.setLoadNativeBillIds(loadNativeBillIds);

        // 创建时间
        Date currentDateTime = DateUtil.getSysDateTime();
        // 创建人
        String createUserId = getLoginCzyId();
        bean.setCreateTime(currentDateTime);
        bean.setCreateUserId(createUserId);
        bean.setUpdateTime(currentDateTime);
        bean.setUpdateUserId(createUserId);

        // 获取其他费用列表
        List<BMasterBillOtherChargePojo> bMasterBillOtherChargePojos = null;
        List<Map> otherChargeList = (List<Map>) jsonMasterBillPojo.get("otherChargeList");
        if (otherChargeList != null && otherChargeList.size() > 0) {
            bMasterBillOtherChargePojos = new ArrayList<>();
            for (Map map : otherChargeList) {
                BMasterBillOtherChargePojo bMasterBillOtherChargePojo = new BMasterBillOtherChargePojo();
                bMasterBillOtherChargePojo.setId(this.getSysStrId());
                // 设置主单其他费用类型
                bMasterBillOtherChargePojo.setMasterBillTypeId(SysConstant.XT_DIC_MASTER_BILL_TYPE.AUTO.getId());
                bMasterBillOtherChargePojo.setMasterBillId(bean.getId());
                bMasterBillOtherChargePojo.setName(DataTypeUtil.toStringObject(map.get("name")));
                bMasterBillOtherChargePojo.setAmount(DataTypeUtil.toDouble(map.get("amount")));
                bMasterBillOtherChargePojo.setComment(DataTypeUtil.toStringObject(map.get("comment")));
                bMasterBillOtherChargePojos.add(bMasterBillOtherChargePojo);
            }
        }
        bean.setBMasterBillOtherChargePojos(bMasterBillOtherChargePojos);


        // 获取加入主单的分单信息
        List<BNativeBillLoadPojo> bNativeBillLoadPojos = null;
        List<Map> nativeBillList = (List<Map>) jsonMasterBillPojo.get("nativeBillList");
        if (nativeBillList != null && nativeBillList.size() > 0) {
            bNativeBillLoadPojos = new ArrayList<>();
            for (Map map : nativeBillList) {
                BNativeBillLoadPojo bNativeBillLoadPojo = new BNativeBillLoadPojo();

                bNativeBillLoadPojo.setId(this.getSysStrId());
                // 设置配载表主单ID
                bNativeBillLoadPojo.setMasterBillId(bean.getId());
                // 设置配载的主单类型
                bNativeBillLoadPojo.setMasterBillTypeId(SysConstant.XT_DIC_MASTER_BILL_TYPE.AUTO.getId());
                // 设置配载表分单ID
                bNativeBillLoadPojo.setNativeBillId(DataTypeUtil.toStringObject(map.get("id")));

                // 班次名称
                bNativeBillLoadPojo.setFlightName(DataTypeUtil.toStringObject(map.get("flightName")));

                // 班次日期
                bNativeBillLoadPojo.setFlightDate(DateUtil.strToDate(DataTypeUtil.toStringObject(map.get("flightDate"))));

                bNativeBillLoadPojo.setLoadNumber(DataTypeUtil.toLongObject(map.get("totalNumber")));
                bNativeBillLoadPojo.setLoadActualWeight(DataTypeUtil.toDouble(map.get("actualWeight")));
                bNativeBillLoadPojo.setLoadChargeableWeight(DataTypeUtil.toDouble(map.get("chargeableWeight")));
                bNativeBillLoadPojo.setLoadVolume(DataTypeUtil.toDouble(map.get("volume")));

                bNativeBillLoadPojos.add(bNativeBillLoadPojo);
            }
        }

        bean.setBNativeBillLoadPojos(bNativeBillLoadPojos);
        return bean;
    }


    //@OperationLogger(oper = SysConstant.OPER_ADD, operTitle = "汽运主单-添加", operMemo = "", classType = BMasterBillAutoPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int insert(BMasterBillAutoPojo pojo) throws Exception {
        if (pojo == null) {
            throwException("添加汽运主单参数错误!");
        }
        return bMasterBillAutoMapper.insert(pojo);
    }

    @OperationLogger(oper = SysConstant.OPER_UPDATE, operTitle = "汽运主单-更新", operMemo = "", classType = BMasterBillAutoPojo.class)
    @Transactional(rollbackFor = {Exception.class})
    public int update(BMasterBillAutoPojo bMasterBillAutoPojo) throws Exception {
        if (bMasterBillAutoPojo == null) {
            throwException("添加汽运主单参数错误!");
        }
        return bMasterBillAutoMapper.update(bMasterBillAutoPojo);
    }

    /**
     * 汽运主单添加
     *
     * @param bMasterBillAutoBean
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int addMasterAutoBill(BMasterBillAutoBean bMasterBillAutoBean) throws Exception {
        if (bMasterBillAutoBean == null) {
            throwException("添加汽运主单参数错误!");
        }

        // 1 汽运主单入库
        int affectRows = SpringAopUtil.getBean(this.getClass()).insert(bMasterBillAutoBean);

        if (affectRows <= SysConstant.INT_ZERO) {
            return SysConstant.INT_ZERO;
        }

        // 2.保存汽运主单其他费用
        List<BMasterBillOtherChargePojo> bMasterBillOtherChargePojos = bMasterBillAutoBean.getBMasterBillOtherChargePojos();
        if (bMasterBillOtherChargePojos != null && !bMasterBillOtherChargePojos.isEmpty()) {
            int otherChargeEffectRows = bMasterBillOtherChargeService.batchInsert(bMasterBillOtherChargePojos);
            if (otherChargeEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }
        }

        // 3.保存汽运主单配载的分单位信息
        List<BNativeBillLoadPojo> bNativeBillLoadPojos = bMasterBillAutoBean.getBNativeBillLoadPojos();
        if (bNativeBillLoadPojos != null && !bNativeBillLoadPojos.isEmpty()) {
            // 批量插入配载分单信息
            int loadEffectRows = bNativeBillLoadService.batchInsertLoadBill(bNativeBillLoadPojos);
            if (loadEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }

            Integer costShareStandard = getCostShareStandard(bMasterBillAutoBean,bNativeBillLoadPojos);

            // 配载分单成本核算
            for (BNativeBillLoadPojo pojo : bNativeBillLoadPojos) {
                bNativeBillLoadService.loadNativeBillCostAccounting(pojo,costShareStandard);
            }

            // 原始分单成本、利润核算
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojos) {
                int nativeUpdateAffectRows = bNativeBillService.nativeBillCostAccounting(loadPojo.getNativeBillId(), false);
            }

        }

        return affectRows;
    }

    public Integer getCostShareStandard(BMasterBillAutoPojo bMasterBillAutoPojo, List<BNativeBillLoadPojo> bNativeBillLoadPojos) {
        // 遍历一下，瞧一瞧整体或个体重量是否超过主单计费重量
        Double loadPojoTotalActualWeight = 0D;
        for(BNativeBillLoadPojo loadPojo : bNativeBillLoadPojos){
            loadPojoTotalActualWeight += loadPojo.getLoadActualWeight();
        }

        Integer costShareStandard= SysConstant.COST_SHARE_STANDARD_WEIGHT;
        if(loadPojoTotalActualWeight > bMasterBillAutoPojo.getActualLoadTotalWeight()){
            costShareStandard = SysConstant.COST_SHARE_STANDARD_NUMBER;
        }
        return costShareStandard;
    }

    /**
     * 根据查询条件参数，查询返回的结果列表
     *
     * @param param 条件参数
     * @return 主单列表对象
     */
    public Object getPageList(Map param) {
        // 设置共公参数
        setQueryCommParam(param);
        this.pageListInit(param);
        List list = bMasterBillAutoMapper.findAll(param);
        MIniUIGridResultMap resultMap = this.pageToGrid(list);
        return resultMap;
    }

    /**
     * 查询主单包含的分单
     *
     * @param param
     * @return
     */
    public Object queryNativeBillList(Map param) {
        return bNativeBillLoadService.queryNativeBillList(param);
    }

    /**
     * 这个查询不分页
     *
     * @param param1
     * @return
     */
    public List<BNativeBillLoadPojo> queryNativeBillListNoPage(Map<String, Object> param1) {
        return bNativeBillLoadService.queryNativeBillListNoPage(param1);
    }

    public List<BMasterBillAutoPojo> getBMasterBillAutoPojoListByInId(String ids) {
        return bMasterBillAutoMapper.getBMasterBillAutoPojoListByInId(ids);
    }

    /**
     * 根据id获取汽运主单对象
     *
     * @param id
     * @return
     */
    public BMasterBillAutoPojo getBMasterBillAutoPojoById(String id) {
        return bMasterBillAutoMapper.getBMasterBillAutoPojoById(id);
    }

    /**
     * 更新汽运主单
     *
     * @param bMasterBillAutoBean
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateMasterAutoBill(BMasterBillAutoBean bMasterBillAutoBean) throws Exception {

        if (bMasterBillAutoBean == null) {
            throwException("更新汽运主单参数错误!");
        }

        if (bMasterBillAutoBean.getDropStatusId().longValue() == SysConstant.XT_DIC_PULL_STATUS.PULL.getId()) {
            throwException("主单已经做过拉货操作，不能进行更新操作!");
        }

        // 设置更新时间与更新人
        bMasterBillAutoBean.setUpdateTime(DateUtil.getSysDateTime());
        bMasterBillAutoBean.setUpdateUserId(this.getLoginCzyId());
        // 开始更新
        int effectRows = SpringAopUtil.getBean(this.getClass()).update(bMasterBillAutoBean);
        if (effectRows <= SysConstant.INT_ZERO) {
            return SysConstant.INT_ZERO;
        }

        // 2.更新航空主单其他费用
        List<BMasterBillOtherChargePojo> bMasterBillOtherChargePojos = bMasterBillAutoBean.getBMasterBillOtherChargePojos();
        if (bMasterBillOtherChargePojos != null && !bMasterBillOtherChargePojos.isEmpty()) {
            // 2.1 先删除航空主单位原来的其他费用
            int delChargeEffectRows = bMasterBillOtherChargeService.deleteByMasterBillId(bMasterBillAutoBean.getId());
            // 2.2 重新插入最新的其他费用
            int otherChargeEffectRows = bMasterBillOtherChargeService.batchInsert(bMasterBillOtherChargePojos);
            if (otherChargeEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }
        }

        // 3.更新主单包含的分单信息
        List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bMasterBillAutoBean.getBNativeBillLoadPojos();
        if (bNativeBillLoadPojoList != null && !bNativeBillLoadPojoList.isEmpty()) {
            // 3.1 删除原来的主单包含的分单
            int delLoadEffectRows = bNativeBillLoadService.deleteLoadNativeBillByMasterBillId(bMasterBillAutoBean.getId());

            // 3.2 重新插入主单包含的最新的分单
            int loadEffectRows = bNativeBillLoadService.batchInsertLoadBill(bNativeBillLoadPojoList);
            if (loadEffectRows <= SysConstant.INT_ZERO) {
                return SysConstant.INT_ZERO;
            }

            Integer costShareStandard = getCostShareStandard(bMasterBillAutoBean,bNativeBillLoadPojoList);

            // 3.3 对新插入的配载分单重新进行成本核算
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                bNativeBillLoadService.loadNativeBillCostAccounting(loadPojo,costShareStandard);
            }

            // 3.4 对配载分单的原始分单进行成本核算
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                bNativeBillService.nativeBillCostAccounting(loadPojo.getNativeBillId(), false);
            }
        }

        return effectRows;
    }

    /**
     * 更新汽运主单状态
     *
     * @param statusFieldName
     * @param statusId
     * @param billIds
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateStatusId(String statusFieldName, Long statusId, String billIds) {
        return bMasterBillAutoMapper.updateStatusId(statusFieldName, statusId, billIds, this.getSysTime(), this.getLoginCzyId());
    }

    @Transactional(rollbackFor = {Exception.class})
    public int changeAccountCheckStatus(Map param) throws Exception {
        // {billIds:canAccountCheckIds,accountCheckStatusId:accountStatus}
        Long accountCheckStatusId = DataTypeUtil.toLongObject(param.get("accountCheckStatusId"));
        String billIds = DataTypeUtil.toStringObject(param.get("billIds"));

        if (accountCheckStatusId.longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.NO_CHECK.getId()) {
            List<BMasterBillAutoPojo> list = getBMasterBillAutoPojoListByInId(billIds);
            String ids = "";
            for (BMasterBillAutoPojo pojo : list) {
                if (pojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()) {
                    ids += pojo.getId() + " ";
                }
            }
            if (ids.length() > 0) {
                ids = ids.trim();
                throwException("汽运主单【" + ids + "】结算状态为已结算，不能修改其对账状态为未对账!");
            }
        }
        return updateStatusId("account_check_status_id", accountCheckStatusId, billIds);
    }

    @Transactional(rollbackFor = {Exception.class})
    public int deleteMasterBillByMasterBillIds(Map param) throws Exception {
        if (param == null || param.isEmpty()) {
            throwException("主单删除参数错误!");
        }
        String masterBillIds = DataTypeUtil.toStringObject(param.get("masterBillIds"));
        if (DataTypeUtil.isEmptyStr(masterBillIds)) {
            throwException("主单删除参数错误!");
        }
        // 返回的影响行数，记录主单被删除的行数
        int affectRows = 0;

        /**
         * 主单删除逻辑
         1.主单删除时如果主单的对账状态是 已对账，已拉货 则不能删除
         2.如果是自发的主单号会被回收，供再次使用
         3.主单删除时其下的相关配载信息会一并删除
         5.分单不会删除，但会修改其配载状态为未配载或部分配载，原分单成本及分单利润会调整为0  drop_status_id
         */
        // 分离主单号为数组
        String[] masterBillIdArray = masterBillIds.split(",");
        // 遍历等待删除的主单号
        for (String masterBillId : masterBillIdArray) {
            // 1.根据主单号加载主单对象
            BMasterBillAutoPojo bMasterBillAutoPojo = getBMasterBillAutoPojoById(masterBillId);
            if (bMasterBillAutoPojo == null) {
                throwException("待删除的主单【" + masterBillId + "】对象不存在，删除主单失败!");
            }

            // 2.检测主单状态
            if (bMasterBillAutoPojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                    || bMasterBillAutoPojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                    || bMasterBillAutoPojo.getDropStatusId().longValue() == SysConstant.XT_DIC_PULL_STATUS.PULL.getId()) {
                throwException("待删除的主单【" + masterBillId + "】对象 已拉货、已对账或已结算，删除主单失败!");
            }

            // 3.根据主单ID 加载主单下的配载列表
            List<BNativeBillLoadPojo> bNativeBillLoadPojoList = bNativeBillLoadService.queryNativeBillListByMasterBillId(masterBillId);
            if (bNativeBillLoadPojoList == null || bNativeBillLoadPojoList.isEmpty()) {
                throwException("待删除的主单【" + masterBillId + "】对象 配载分单为空，删除主单失败!");
            }

            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                String nativeBillId = loadPojo.getNativeBillId();
                // 检测配载列表中的分单是否做过拉货或对账或结算状态
                BNativeBillPojo bNativeBillPojo = bNativeBillService.getBNativeBillPojoById(nativeBillId);
                // 检测分单对象是否存在
                if (bNativeBillPojo == null) {
                    throwException("待删除的主单【" + masterBillId + "】对象下的配载分单【" + nativeBillId + "】对象在分单表中不存在，删除主单失败!");
                }
                // 检测分单对象是否做过拉货、对过账、结算过
                if (bNativeBillPojo.getSettlementStatusId().longValue() == SysConstant.XT_DIC_SETTLEMENT_STATUS.CLEARED.getId()
                        || bNativeBillPojo.getAccountCheckStatusId().longValue() == SysConstant.XT_DIC_ACCOUNT_CHECK_STATUS.CHECKED.getId()
                        || bNativeBillPojo.getDropStatusId().longValue() == SysConstant.XT_DIC_PULL_STATUS.PULL.getId()) {
                    throwException("待删除的主单【" + masterBillId + "】下的配置分单【" + nativeBillId + "】对象 已拉货、已对账或已结算，删除主单失败!");
                }

                // 调用删除，把该配载信息给删除
                int deleteBillLoadAffectRows = bNativeBillLoadService.delete(loadPojo.getId());
            }

            // 到此该主单下的所有配载信息删除完成,下面根据已经删除的配载信息做遍历更新原始分单相应的配载状态,因为可能一分单被配载到多个主单，但我们只删除了一个主单
            for (BNativeBillLoadPojo loadPojo : bNativeBillLoadPojoList) {
                String nativeBillId = loadPojo.getNativeBillId();
                Map<String, Object> cndParam = new HashMap<>();
                cndParam.put("billId", nativeBillId);
                List<BNativeBillLoadPojo> billLoadPojoList = bNativeBillLoadService.queryNativeBillListNoPage(cndParam);

                // 定义默认总配载件数
                long totalLoadNumber = 0;
                // 定义还剩余的配载主单号
                Set<String> billLoadMasterBillSet = new HashSet<>();
                if (billLoadPojoList != null && !billLoadPojoList.isEmpty()) {
                    for (BNativeBillLoadPojo pojo : billLoadPojoList) {
                        totalLoadNumber += pojo.getLoadNumber();
                        billLoadMasterBillSet.add(pojo.getMasterBillId());
                    }
                }
                String billLoadMasterBillIds = "";
                if (!billLoadMasterBillSet.isEmpty()) {
                    for (String masterId : billLoadMasterBillSet) {
                        billLoadMasterBillIds += masterId + ",";
                    }
                }

                if (billLoadMasterBillIds.length() > 0) {
                    billLoadMasterBillIds.substring(0, billLoadMasterBillIds.length() - 1);
                }

                // 获取原始分单对象
                BNativeBillPojo bNativeBillPojo = bNativeBillService.getBNativeBillPojoById(nativeBillId);

                bNativeBillPojo.setBillLoadMasterBillIds(billLoadMasterBillIds);
                bNativeBillPojo.setShareCost(0D);
                bNativeBillPojo.setGrossProfit(0D);
                bNativeBillPojo.setShareCostComment("");


                if (totalLoadNumber == 0) {
                    bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.NO_LOAD.getId());
                } else {
                    bNativeBillPojo.setBillLoadStatusId(SysConstant.XT_DIC_BILL_LOAD_STATUS.PART_LOAD.getId());
                }

                // 更新分单对象
                int updateNativeBillAffectRows = bNativeBillService.update(bNativeBillPojo);
            }

            // 下面删除主的其他费用
            int deleteMasterBillOtherChargeAffectRows = bMasterBillOtherChargeService.deleteByMasterBillId(masterBillId);

            // 最后删除主单对象
            affectRows += this.delete(masterBillId);
        }

        return affectRows;
    }

    @Transactional(rollbackFor = {Exception.class})
    public int delete(String id) throws Exception {
        if (DataTypeUtil.isEmptyStr(id)) {
            throwException("删除航空主单ID参数错误!");
        }
        return bMasterBillAutoMapper.delete(id);
    }

    /**
     * 根据汽运主单号加载该主单对应的配载分单对象
     *
     * @param masterBillId
     * @return
     */
    public List<BNativeBillPojo> queryBNativeBillPojoListByMasterBillId(String masterBillId) throws Exception {
        if (DataTypeUtil.isEmptyStr(masterBillId)) {
            throwException("主单号查询分单列表参数错误!");
        }

        List<BNativeBillPojo> bNativeBillPojoList = bNativeBillService.queryBNativeBillPojoListByMasterBillId(masterBillId);

        return bNativeBillPojoList;
    }
}
